<%@ page contentType="application/json; charset=UTF-8"  pageEncoding="UTF-8" errorPage="/error.jsp"%>
<%@page import="dbexp.model.Package"%>
<%@page import="java.util.Iterator"%>
<%@page import="dbexp.model.db.DbOT"%>
<%@page import="dbexp.connection.DbMetaData"%>
<%@page import="java.util.List"%>
<%@page import="java.util.ArrayList"%>
<%@page import="org.json.JSONException"%>
<%@page import="dbexp.model.*"%>
<%@page import="org.json.JSONArray"%>
<%@page import="dbexp.utils.Unicode"%>
<%@page import="org.json.JSONObject"%>
<%@page import="java.io.OutputStreamWriter"%>
<%@page import="java.io.Writer"%>
<%@page import="java.util.Enumeration"%>
<%@page import="dbexp.model.db.DbUser"%>
<%@page import="java.util.HashMap"%><%!
HashMap<String,DbObject[]> categories = new HashMap<String,DbObject[]>();
HashMap<String,DbObject[]> dbObjects = new HashMap<String,DbObject[]>();
DbUser u = null;
HashMap<String,DbObject[]> security = new HashMap<String,DbObject[]>();
HashMap<String,DbObject[]> secObjects = new HashMap<String,DbObject[]>();
String ROOT = "root";
String SECURITY = "security";
%><%
String resp = error("Nieznana akcja");
String resetTree = request.getParameter("reset");
session = request.getSession(false);
boolean show = (request.getParameter("show")!=null)?Boolean.parseBoolean(request.getParameter("show")):true;
if(session==null){
	System.out.println("session null");
}else if(session.isNew()){
	System.out.println("Nowa sessja");
}else{
	u = (DbUser)session.getAttribute("USER");
	if(u==null){
		u = new DbUser("ORA9I", "localhost", "qazxsw", 1521, "SYSTEM");
		u = DbMetaData.createConnection(u);
		session.setAttribute("USER",u);
	}
	if(u!=null){
		if(resetTree != null){
			response.setStatus(HttpServletResponse.SC_OK);
			System.out.println("reset");
			return;
		}
		if(session.getAttribute("categories")==null || session.getAttribute("dbObjects")==null){
			initDBObjects(session);
		}else{
			categories = (HashMap<String,DbObject[]>)session.getAttribute("categories");
			dbObjects = (HashMap<String,DbObject[]>)session.getAttribute("dbObjects");
		}
		if(session.getAttribute("security")==null || session.getAttribute("secObjects")==null){
			initSecObjects(session);
		}else{
			security = (HashMap<String,DbObject[]>)session.getAttribute("security");
			secObjects = (HashMap<String,DbObject[]>)session.getAttribute("secObjects");
		}
		String cmd = request.getParameter("cmd");
		String path = Unicode.decode(request.getParameter("path"));
		String schema = Unicode.decode(request.getParameter("schema"));
		String type = Unicode.decode(request.getParameter("type"));
		String name = Unicode.decode(request.getParameter("name"));
		System.out.println("wartosc cmd:"+cmd);
		System.out.println("wartosc path:"+path);
		System.out.println("wartosc schema:"+schema);
		System.out.println("wartosc name:"+name);
		System.out.println("wartosc type:"+type);
		if(schema == null){
			schema = "";
		}
		if(cmd == null && path != null){
			cmd = "get";
		}else if(cmd == null && path==null){
			try {
				JSONObject jo = new JSONObject();
				jo.put("success", false);
				jo.put("error", "Nieznana akcja");
				resp = jo.toString();
			} catch (Exception e) {
				resp = error("Nieznana akcja");
			}
		}
		if(cmd == null && path==null){
			try {
				JSONObject jo = new JSONObject();
				jo.put("success", false);
				jo.put("error", "Nieznana komenda");
				resp = jo.toString();
			} catch (Exception e) {
				resp = error("Nieznana komenda");
			}
		}else{
			//resp = getSchemas();
			if(cmd.equals("get")){
				System.out.println("get");
				resp = doGetDbObjects(path,schema);
			}else if(cmd.equals("gets")){
				System.out.println("gets");
				resp = doGetDbObjects(path,schema);
			}else if(cmd.equals("delete")){
				resp = doDeleteDbObject(path,schema, type);
			}else if(cmd.equals("getSchemas")){
				resp = getSchemas();
			}else if(cmd.equals("getSec")){
				resp = getSec(path);
			}					
		}
	}
}
Enumeration en = request.getParameterNames();
while (en.hasMoreElements()) {
	String elem = (String) en.nextElement();
	System.out.print("name = " + elem);
	System.out.println("; value = " + request.getParameterValues(elem)[0]);
}
if(response!=null){
	//response.setContentType("application/json");
	//response.setStatus(HttpServletResponse.SC_OK);
	if(show){
		out.clearBuffer();out.print(Unicode.encode(resp));
	}
}%><%!
public String doDeleteDbObject(String o, String s, String t){
	String retval = "{\"success\":false,\"error\":\"Nie mozna usunac obiektu\"}";
	String path = "";
	int typ = DbOT.UNKNOWN;
	path = "root/schemy/"+s;
		try{
			typ = Integer.parseInt(t);
		}catch(NumberFormatException nfe){
			
		}
	path += "/" + DbOT.getNameOfType(typ);
System.out.println("t:"+t);		
System.out.println("s:"+s);		
System.out.println("o:"+o);
System.out.println("path:"+path);
		if(dbObjects.containsKey(path)){
			DbObject[] oldOfObject = dbObjects.get(path);
			DbObject[] listOfObject = new DbObject[oldOfObject.length-1];
			try{
				for(int i = 0,j = 0; i< oldOfObject.length;i++){
					if(oldOfObject[i]!=null && oldOfObject[i].getName().equals(o)){
						//if(DbMetaData.removeObject(u, s ,o, typ)){
							retval = success();
						//}else{
							return out(retval);
						//}
					}else{
						listOfObject[j++]=oldOfObject[i];
					}
				}
				dbObjects.remove(path);
				dbObjects.put(path,listOfObject);
			}catch(Exception e) {
				e.printStackTrace();
				return out(error(e.getMessage()));
			}
		}
		retval = success();
	
	return out(retval);
}
private String doGetDbObjects(String p, String schema){
	JSONArray ja = new JSONArray();
	System.out.println("serwer path przed:"+p);
	String path = "";
	int typ = DbOT.UNKNOWN;
	if(p.startsWith(ROOT+"/"+schema)){//czy uzytkownik chce otrzymac kategorie obiekt�w
		path = p.replaceAll(ROOT+"/"+schema, ROOT+"/"+Schema.LABEL+"/"+schema);
		if(!categories.containsKey(path)){
				categories.put(ROOT+"/"+Schema.LABEL+"/"+schema,new DbObject[]{new Table(),new Index(), 
				new View(),new Synonym(),new Sequence(),
				new SourceType()});
		}
	}else{//w przeciwnym wypadku chce otrzymac obiekty danej kategorii
		try{
			typ = Integer.parseInt(p);
		}catch(NumberFormatException nfe){
			
		}
		path = ROOT+"/"+Schema.LABEL+"/"+schema+"/" + DbOT.getNameOfType(typ);
	}
	System.out.println("serwer path po:"+path);
	System.out.println("schema:"+schema);
	// szukanie w kategoriach struktur(schemy(wszystkie schemy)) )
	String category = path.substring(path.lastIndexOf("/")+1);
	if(categories.containsKey(path)){
		DbObject subdirs[] = (DbObject[])categories.get(path);
		String icon = "folder";
		for (int i = 0; i < subdirs.length; i++) {
			try {
				JSONObject jo = new JSONObject();
					jo.put("text", subdirs[i].getName());
					icon = subdirs[i].getIcon();
					typ = subdirs[i].getType();
					category = subdirs[i].getName();
					jo.put("iconCls", icon);
					jo.put("t",String.valueOf(typ));
					if(categories.containsKey(path+"/"+category) ||
						dbObjects.containsKey(path+"/"+category) || subdirs[i].is("leaf")){
						jo.put("leaf", false);
					}else{
						jo.put("leaf", true);
					}
				ja.put(jo);
			} catch (JSONException e) {
				e.printStackTrace();
				return out(error(e.getMessage()));
			}
		}
	}else{
		System.out.println("categories.containsKey(path)=="+categories.containsKey(path));
		System.out.println("categories.size()=="+categories.size());
	}
	// szukamy wszystkich obiektow (struktur)
	if(dbObjects.containsKey(path)){
		try{
			if(category.equals(Table.LABEL)){
				dbObjects.put(path,putIn(u, new Table(null,schema)));
			}else if(category.equals(View.LABEL)){
				dbObjects.put(path,putIn(u, new View(null,schema)));
			}else if(category.equals(Procedure.LABEL)){
				dbObjects.put(path,putIn(u, new Procedure(null,schema)));
			}else if(category.equals(Function.LABEL)){
				dbObjects.put(path,putIn(u, new Function(null,schema)));
			}else if(category.equals(Trigger.LABEL)){
				dbObjects.put(path,putIn(u, new Trigger(null,schema)));
			}else if(category.equals(Sequence.LABEL)){
				dbObjects.put(path,putIn(u, new Sequence(null,schema)));
			}else if(category.equals(Index.LABEL)){
				dbObjects.put(path,putIn(u, new Index(null,schema)));
			}else if(category.equals(Synonym.LABEL)){
				dbObjects.put(path,putIn(u, new Synonym(null,schema)));
			}else if(category.equals(Package.LABEL)){
				dbObjects.put(path,putIn(u, new Package(null,schema)));
			}else if(category.equals(PackageBody.LABEL)){
				dbObjects.put(path,putIn(u, new PackageBody(null,schema)));
			}
		}catch (Exception e) {
			System.out.println(e);
			e.printStackTrace();
			return out(error(e.getMessage()));
		}
		DbObject fls[] = (DbObject[])dbObjects.get(path);
		String icon = "file-txt";
		typ = DbOT.UNKNOWN;
		for (int i = 0; i < fls.length; i++) {
			try {
				if(fls[i].isUnknown()){
					continue;
				}
				JSONObject jo = new JSONObject();
					jo.put("text", fls[i].getName());
					icon = fls[i].getIcon();
					jo.put("iconCls", icon);
					jo.put("leaf", true);
//					jo.put("qtip", "Opis obiektu: " + fls[i]);
					typ = fls[i].getType();
					jo.put("t",String.valueOf(typ));
				ja.put(jo);
			} catch (JSONException e) {
				e.printStackTrace();
				return out(error(e.getMessage()));
			}
		}
	}else{
		System.out.println("dbObjects.containsKey(path)=="+dbObjects.containsKey(path));
		System.out.println("dbObjects.size()=="+dbObjects.size());
	}
	return out(ja.toString());
}
private DbObject[] putIn(DbUser u,DbObject o)throws Exception{
	List<DbObject> sy = new ArrayList<DbObject>();
	if(!o.isUser() && !o.isRole()){
		sy = DbMetaData.getObjects(u, o);
	}else{
		sy = DbMetaData.getSecurityObjects(u, o);
	}
	DbObject[] syArray = new DbObject[sy.size()];
	for(int i =0; i<sy.size();i++){
		syArray[i] = sy.get(i);
	}
	return syArray;
}
@SuppressWarnings("unused")
private String getSchemaName(String path){
	return out(path.substring(path.lastIndexOf("/")+1));
}
private String getSchemas(){
	JSONObject schemyMainObject = new JSONObject();
	JSONArray schemy = new JSONArray();
	try{
		List<Schema> schemas = DbMetaData.getAllSchemas(u);
		schemyMainObject.put("count", schemas.size());
		for(int i =0; i<schemas.size();i++){
			Schema s = (Schema)schemas.get(i);
			JSONObject schema = new JSONObject();
			schema.put("name",s.getName());
			schemy.put(schema);
		}
		schemyMainObject.put("data",schemy);
	}catch(Exception e) {
		e.printStackTrace();
		return out(error(e.getMessage()));
	}
	return out(schemyMainObject.toString());
}
private void initDBObjects(HttpSession session){
	JSONObject schemyMainObject = new JSONObject();
	JSONArray schemy = new JSONArray();
	try{
		List<Schema> schemas = DbMetaData.getAllSchemas(u);
	Schema[] schemasArray = new Schema[schemas.size()];
		schemyMainObject.put("count", schemas.size());
	for(int i =0; i<schemas.size();i++){
		schemasArray[i] = (Schema)schemas.get(i);
	}
	categories.put(ROOT+"/"+Schema.LABEL, schemasArray);
		for (int i = 0; i < schemasArray.length; i++) {
			categories.put(ROOT+"/"+Schema.LABEL+"/"+schemasArray[i],new DbObject[]{new Table(),new Index(), 
					new View(),new Synonym(),new Sequence(),
					new SourceType()});
			categories.put(ROOT+"/"+Schema.LABEL+"/"+schemasArray[i]+"/"+SourceType.LABEL,
					new DbObject[]{
						new Package(),new PackageBody(),
					new Procedure(),	new Function(),
					new Trigger()}); 			
						dbObjects.put(ROOT+"/"+Schema.LABEL+"/"+schemasArray[i]+"/"+Table.LABEL, new NONE[]{new NONE()});
						dbObjects.put(ROOT+"/"+Schema.LABEL+"/"+schemasArray[i]+"/"+Index.LABEL, new NONE[]{new NONE()});
						dbObjects.put(ROOT+"/"+Schema.LABEL+"/"+schemasArray[i]+"/"+View.LABEL, new NONE[]{new NONE()});
						dbObjects.put(ROOT+"/"+Schema.LABEL+"/"+schemasArray[i]+"/"+Synonym.LABEL, new NONE[]{new NONE()});
						dbObjects.put(ROOT+"/"+Schema.LABEL+"/"+schemasArray[i]+"/"+Sequence.LABEL, new NONE[]{new NONE()});
						dbObjects.put(ROOT+"/"+Schema.LABEL+"/"+schemasArray[i]+"/"+SourceType.LABEL+"/"+Package.LABEL, new NONE[]{new NONE()});
						dbObjects.put(ROOT+"/"+Schema.LABEL+"/"+schemasArray[i]+"/"+SourceType.LABEL+"/"+PackageBody.LABEL, new NONE[]{new NONE()});
						dbObjects.put(ROOT+"/"+Schema.LABEL+"/"+schemasArray[i]+"/"+SourceType.LABEL+"/"+Procedure.LABEL, new NONE[]{new NONE()});
						dbObjects.put(ROOT+"/"+Schema.LABEL+"/"+schemasArray[i]+"/"+SourceType.LABEL+"/"+Function.LABEL, new NONE[]{new NONE()});
						dbObjects.put(ROOT+"/"+Schema.LABEL+"/"+schemasArray[i]+"/"+SourceType.LABEL+"/"+Trigger.LABEL, new NONE[]{new NONE()});

			JSONObject schema = new JSONObject();
			schema.put("name", schemasArray[i].getName());
			schemy.put(schema);
		}
		schemyMainObject.put("schemas",schemy);
		if(session!=null){
			session.setAttribute("categories",categories);
			session.setAttribute("dbObjects",dbObjects);
		}
	}catch(Exception e) {
		e.printStackTrace();
	}
}
private void initSecObjects(HttpSession session){
	try{
		security.put(ROOT+"/"+SECURITY,new DbObject[]{new User()});
		secObjects.put(ROOT+"/"+SECURITY+"/"+User.LABEL,putSecurityObject(u, new User(null)));
		if(session!=null){
			session.setAttribute("security",security);
			session.setAttribute("secObjects",secObjects);
		}
	}catch(Exception e) {
		e.printStackTrace();
	}
}
private DbObject[] putSecurityObject(DbUser u,DbObject o)throws Exception{
	List<DbObject> sy = new ArrayList<DbObject>();
		sy = DbMetaData.getSecurityObjects(u, o);
	DbObject[] syArray = new DbObject[sy.size()];
	for(int i =0; i<sy.size();i++){
		syArray[i] = sy.get(i);
	}
	return syArray;
}
private String getSec(String p){
	JSONArray secs = new JSONArray();	
	System.out.println("serwer path przed:"+p);
	String path = "";
	int typ = DbOT.UNKNOWN;
	if(p.startsWith(ROOT+"/")){//czy uzytkownik chce otrzymac kategoric obiektow
		path = ROOT+"/"+SECURITY;
	}else{//w przeciwnym wypadku chce otrzymac obiekty danej kategorii
		try{
			typ = Integer.parseInt(p);
		}catch(NumberFormatException nfe){
		}
		path = ROOT+"/"+SECURITY+"/" + DbOT.getNameOfType(typ);
	}
	String category = path.substring(path.lastIndexOf("/")+1);
	if(security.containsKey(path)){
		DbObject subdirs[] = (DbObject[])security.get(path);
		String icon = "folder";
		for (int i = 0; i < subdirs.length; i++) {
			try {
				JSONObject jo = new JSONObject();
					jo.put("text", subdirs[i].getName());
					icon = subdirs[i].getIcon();
					typ = subdirs[i].getType();
					category = subdirs[i].getName();
					jo.put("iconCls", icon);
					jo.put("t",String.valueOf(typ));
					if(security.containsKey(path+"/"+category) ||
							secObjects.containsKey(path+"/"+category) || subdirs[i].is("leaf")){
						jo.put("leaf", false);
					}else{
						jo.put("leaf", true);
					}
					secs.put(jo);
			} catch (JSONException e) {
				e.printStackTrace();
				return out(error(e.getMessage()));
			}
		}
	}
	if(secObjects.containsKey(path)){
		if(category.equals(User.LABEL)){
			try{
				secObjects.put(path,putSecurityObject(u, new User(null)));
			}catch (Exception e) {
				System.out.println(e);
				e.printStackTrace();
				return out(error(e.getMessage()));
			}
		}
		DbObject fls[] = (DbObject[])secObjects.get(path);
		String icon = "file-txt";
		typ = DbOT.UNKNOWN;
		for (int i = 0; i < fls.length; i++) {
			try {
				if(fls[i].isUnknown()){
					continue;
				}
				JSONObject jo = new JSONObject();
					jo.put("text", fls[i].getName());
					icon = fls[i].getIcon();
					jo.put("iconCls", icon);
					jo.put("leaf", true);
//					jo.put("qtip", "Opis obiektu: " + fls[i]);
					typ = fls[i].getType();
					jo.put("t",String.valueOf(typ));
					secs.put(jo);
			} catch (JSONException e) {
				e.printStackTrace();
				return out(error(e.getMessage()));
			}
		}
	}
	return out(secs.toString());
}
private JSONObject getNode(DbObject o){
	if(o == null){
		return new JSONObject();
	}
	return getNode(o.getName(), o.getIcon(), o.is("leaf"), o.getType(), o.getString("remark")); 
}
private JSONObject getNode(String text, String icon, boolean leaf, int t, String qtip){
	JSONObject jo = new JSONObject();
	try{
		jo.put("text", text);
		jo.put("iconCls", icon);
		jo.put("leaf", leaf);
		if(qtip!=null && qtip.length()>0){
			jo.put("qtip", qtip);
		}
		jo.put("t",String.valueOf(t));
	}catch(Exception w){}
	return jo;
}
public String error(String error){
	return out("{\"success\":false,\"error\":\""+error+"\"}");
}
public String success(){
	return "{\"success\":true}";
}
public String out(String out){
	System.out.println("out:"+out);
	return Unicode.encode(out.toString());
}
%>